虚拟内存 I
AP SHANTHI博士
本模块的目标是讨论虚拟内存的概念并讨论虚拟内存的各种实现。
我们都知道这样一个事实,即我们的程序需要在主内存中可用,以便处理器执行它。假设您的计算机有 32 或 64 MB RAM 可供 CPU 使用。不幸的是,这个 RAM 量不足以运行大多数用户希望一次运行的所有程序。例如,如果您将操作系统、电子邮件程序、Web 浏览器和文字处理器同时加载到 RAM 中,32 MB 不足以容纳所有这些。如果没有虚拟内存之类的东西,那么除非关闭某个程序,否则您将无法运行您的程序。对于虚拟内存,我们不会将程序视为一个整体。我们把它分成几部分,只有当前被处理器引用的一部分需要在主内存中可用。整个程序在硬盘中可用。由于硬盘和主内存之间的复制是自动发生的,您甚至不知道它正在发生,这让您的计算机感觉拥有无限的 RAM 空间,即使它只安装了 32 MB。由于硬盘空间比 RAM 芯片便宜得多,因此它也具有经济效益。
在需要执行时自动将程序和数据块移动到物理主内存中的技术称为虚拟内存技术。程序以及处理器引用独立于可用物理主存储器空间的指令和数据空间。处理器为指令或数据发出的二进制地址称为虚拟地址或逻辑地址。这些地址通过硬件和软件组件的组合转换为物理地址。如果虚拟地址指的是当前位于物理内存中的程序或数据空间的一部分,则立即访问主内存中适当位置的内容。另一方面,如果引用的地址不在主存中,则其内容必须先放入内存中的合适位置才能使用。因此,程序员使用的地址将被称为虚拟地址,而这些地址的集合就是地址空间。主存储器中的地址称为位置或物理地址。这些位置的集合称为内存空间,它由可直接寻址以进行处理的实际主内存位置组成。例如,考虑一台主内存容量为 32M 字的计算机。由于 32 M = 225,因此需要 25 位来指定内存中的物理地址。假设计算机有 可用的辅助内存来存储 235,即 32G 字。因此,辅助存储器的信息存储容量相当于1024个主存储器的容量。用 N 表示地址空间,用 M 表示内存空间,对于这个例子,我们有 N = 32 Giga 字和 M = 32 Mega 字。
在主存储器和辅助存储器之间移动的程序部分可以是固定大小(页)或可变大小(段)。虚拟内存还允许程序的内存在物理上是不连续的,这样每个部分都可以在有可用空间的地方分配。这有利于进程重定位。虚拟内存除了克服主内存大小限制外,还允许在进程之间共享主内存。因此,虚拟内存模型提供了程序使用的地址(虚拟)和内存地址(物理)的解耦。因此,虚拟内存的定义可以表述为“用户逻辑内存与物理内存的概念分离,以便在小的物理内存上拥有大的虚拟内存”。它给人一种无限存储的错觉,
即使程序生成虚拟地址,这些地址也不能用于访问物理内存。因此,必须完成虚拟地址到物理地址的转换。这是由内存管理单元 (MMU) 完成的。映射是一个动态操作,这意味着当 CPU 引用一个字时,每个地址都会立即转换。这个概念在图 30.1 和 30.2 中进行了图示。图 30.1 给出了逻辑地址和物理地址之间映射的一般概述。图 30.2 显示了如何映射四个不同的页面 A、B、C 和 D。请注意,即使它们在虚拟空间中是连续的页面,它们在物理空间中也不是这样。页 A、B 和 C 在非连续位置的物理内存中可用,而页 D 在物理存储中不可用。
使用分页的地址映射:如果将地址空间和内存空间中的信息分别分成固定大小的组,则简化地址映射。物理内存被分成大小相等的组,称为页框,逻辑内存被分成页面相同的大小。程序也被认为是分页的。页的长度通常在 2K 到 16K 字节之间。它们构成了信息的基本单元,每当转换机制确定需要移动时,这些信息就会在主存储器和磁盘之间移动。页不要太小,因为磁盘的访问时间比主存的访问时间长很多。这样做的原因是在磁盘上定位数据需要相当长的时间,但是一旦定位,数据可以以每秒几兆字节的速度传输。另一方面,如果页面太大,页面的很大一部分可能不会被使用,但这些不必要的数据将占用主内存中的宝贵空间。如果考虑一台地址空间为 1M,内存空间为 64K 的计算机,如果将每台计算机分成 2K 个字的组,您将获得 29 (512) 个页面和三十二个页框。在任何给定时间,多达 32 页的地址空间可以驻留在主存储器中的 32 个块中的任何一个中。
为了进行映射,虚拟地址由两个数字表示:页号和页内的偏移量或行地址。在每页有 2 p 个字的计算机中,p位用于指定偏移量,虚拟地址的其余高位指定页码。在上面的例子中,我们考虑了一个20 位的 虚拟地址。由于每个页面由 211 = 2K 个字组成,虚拟地址的高 9 位将指定 512 个页面之一,低 11 位给出页面内的偏移量。注意地址空间和内存空间中的行地址是一样的;唯一需要的映射是从页码到块号。
页和页框之间的映射信息在页表中可用。页表由虚拟地址可以支持的页数组成。页表的基地址存储在称为页 表基址寄存器 (PTBR) 的寄存器中。每个进程都可以有一个或多个自己的页表,操作系统通过将不同的地址加载到 PTBR 中,在上下文切换时从一个页表切换到另一个页表。页号是虚拟地址的一部分,用于索引到适当的页表条目。如果页面在主内存中可用,则页表条目包含物理页框地址。否则,它指定二级存储,页面可用的位置。这会产生页面错误,操作系统将请求的页面从辅助存储带到主存储。除了这个地址信息,页表条目还提供了关于与页面相关联的权限级别和页面访问权限的信息。这有助于为页面提供保护。映射过程如图 30.3 所示。图 30.4 显示了一个典型的页表条目。脏位或修改位指示页面是否在缓存驻留期间被修改。
图 30.4
M – 表示页面是否已写入(脏)
R – 表示页面是否已被引用(用于替换)
V – 有效位
保护位 - 指示在此页面上允许进行哪些操作
Page Frame Number 表示页面在内存中的位置
因此,虚拟内存系统是硬件和软件技术的结合。内存管理软件系统处理所有软件操作以有效利用内存空间。它必须决定分层记忆系统中常见的四个问题的答案:
Q1:上层哪里可以放置方块?
Q2:如果块在上层,如何找到?
Q3: 哪个方块应该在未命中时更换?
Q4:写入时会发生什么?
硬件映射机制和内存管理软件共同构成了虚拟内存的架构并回答了所有这些问题。
当一个程序开始执行时,一个或多个页面被传送到主存中,并设置页表以指示它们的位置。因此,页表条目有助于识别页面。该程序从主内存执行,直到它尝试引用仍在辅助内存中的页面。这种情况称为页面错误。当页面错误发生时,当前程序的执行被暂停,直到所需的页面被带入主存储器。由于从辅助内存加载一个页面到主内存基本上是一个 I/O 操作,操作系统将这个任务分配给 I/O 处理器。同时,控制转移到内存中等待 CPU 处理的下一个程序。之后,当内存块被分配并且传输完成时,原始程序可以恢复其操作。应该注意的是,由于与磁盘访问相关的访问时间很长,因此始终采用回写策略。此外,当出现页面错误时,内存可能已经满了。在这种情况下,正如我们针对缓存所讨论的那样,必须进行替换。替换策略再次是 FIFO 和 LRU。FIFO 替换策略具有易于实施的优点。!t 的缺点是在某些情况下页面从内存中删除和加载过于频繁。LRU 策略更难实现,但在假设最近最少使用的页面比 FIFO 中最近最少加载的页面更适合移除的假设下,LRU 策略更具吸引力。LRU 算法可以通过将计数器与主存储器中的每个页面相关联来实现。当一个页面被引用时,它的相关计数器被设置为零。在固定 LRU 策略更难实现,但在假设最近最少使用的页面比 FIFO 中最近最少加载的页面更适合移除的假设下,LRU 策略更具吸引力。LRU 算法可以通过将计数器与主存储器中的每个页面相关联来实现。当一个页面被引用时,它的相关计数器被设置为零。在固定 LRU 策略更难实现,但在假设最近最少使用的页面比 FIFO 中最近最少加载的页面更适合移除的假设下,LRU 策略更具吸引力。LRU 算法可以通过将计数器与主存储器中的每个页面相关联来实现。当一个页面被引用时,它的相关计数器被设置为零。在固定 在时间间隔内,与内存中当前所有页面相关联的计数器加 1。最近最少使用的页面是具有最高计数的页面。计数器通常被称为老化寄存器,因为它们的计数表明它们的寿命,即它们的关联页面在多长时间前被引用。
虚拟内存的缺点: 到目前为止,我们假设页表存储在内存中。由于页表信息由 MMU 使用,MMU 进行虚拟到物理地址的转换,对于每次读写访问,程序的每次内存访问至少需要两倍的时间:一次内存访问获取物理地址和第二次访问以获取数据。因此,理想情况下,页表应位于 MMU 内。不幸的是,页表可能相当大,而且由于 MMU 通常作为处理器芯片的一部分来实现,因此不可能在该芯片上包含完整的页表。因此,页表保存在主存中。但是,可以在 MMU 中容纳一小部分页表的副本。这部分由与最近访问的页面相对应的页表条目组成。为此,将翻译后备缓冲器(TLB) 并入 MMU。TLB 存储最新的逻辑到物理地址转换。TLB对主存中页表的操作,本质上和我们结合缓存讨论过的操作是一样的。图 30.5 显示了使用关联映射技术的 TLB 的可能组织。在商业产品中也可以找到集关联映射的 TLB。除了物理地址之外,TLB 还提供了有关页面有效性的信息、它在物理内存中是否可用的状态、保护信息等。
一个基本要求是 TLB 的内容与内存中页表的内容一致。当操作系统更改页表的内容时,它必须同时使 TLB 中的相应条目无效。TLB 中的有效位就是为此目的提供的。当条目无效时,TLB 将获取新信息作为 MMU 对访问未命中的正常响应的一部分。
随着 TLB 的引入,地址转换过程如下。给定 一个虚拟地址,MMU 在 TLB 中查找所引用的页面。如果在TLB 中找到了该页的页表条目,则立即获得物理地址。如果TLB 中存在未命中,则从主存储器中的页表中获取所需条目并更新TLB。
回想一下缓存需要一个物理地址,除非我们使用虚拟缓存。正如关于缓存优化所讨论的那样,带有 TLB 的机器更进一步减少循环/缓存访问的数量。它们将缓存访问与 TLB 访问重叠。也就是说,虚拟地址的高位用于查看 TLB,而低位用作缓存的索引。流程如下所示。
重叠访问仅在用于索引缓存的地址位不因 VA 转换而改变时才有效。如果您想要大缓存,这通常将事情限制为小缓存、大页面大小或高 n 路集关联缓存。
最后,我们将介绍分层存储系统中可能发生的未命中类型。这再次类似于我们已经讨论过的关于高速缓存的未命中。遗漏总结如下:
• 强制未命中:
– 以前从未分页到内存中的页面
– 我们如何消除这些未命中?
• 预取:在需要之前将它们加载到内存中
• 需要以某种方式预测未来!
• 容量未命中:
- 内存不足。必须以某种方式增加大小。
– 我们可以这样做吗?
一种选择:增加DRAM的数量
另一种选择:如果内存中有多个进程:调整分配给每个进程的内存百分比!
冲突未命中:
– 从技术上讲,虚拟内存中不存在冲突未命中,因为它是“完全关联”的缓存
政策失误:
– 当页面在内存中时引起,但由于替换策略而过早地被踢出
- 怎么修?更好的更换政策
总而言之,我们已经了解了对虚拟内存概念的需求。虚拟内存是使用硬件和软件实现的概念。对程序大小的限制不是基于 RAM 大小,而是基于虚拟内存大小。存在三种不同的实现虚拟内存的方法。MMU 执行逻辑到物理地址的转换。分页使用固定大小的页面在主存储器和辅助存储器之间移动。分页使用页表将逻辑地址映射到物理地址。因此,虚拟内存有助于动态分配所需数据、共享数据和提供保护。TLB 用于存储最近的逻辑到物理地址转换。